from drf_yasg2 import openapi
from drf_yasg2.utils import swagger_auto_schema
from rest_framework import viewsets, status
from erp_system.models import PermissionsModel, RolesModel,MenuModel
from rest_framework.decorators import action
from rest_framework.response import Response
from PAA_ERP.apps.erp_system.serializer.roles_seriailizer import RolesPartialSerializer, RoleSetPermissionSerializer, \
    BaseRolesSerializer
from PAA_ERP.utils.base_views import MultipleDestroyMixin


# 角色数据库中有一个固定角色：admin这个角色代表所有权限，它不能删除
class RolesView(viewsets.ModelViewSet, MultipleDestroyMixin):
    """
    create:
    角色--新增 角色新增,

    status: 201(成功), return: 新增角色信息

    destroy:
    角色--删除 角色删除,

    status: 204(成功), return: None

    multiple_delete:
    角色--批量删除 角色批量删除,

    status: 204(成功), return: None

    update:
    角色--修改,不能修改角色，只是修改角色名字。 角色修改,

    status: 200(成功), return: 修改后的角色信息

    partial_update:
    角色--局部修改(角色批量授权),只能真的某一个角色一次性授权，之前的的授权会被覆盖 角色批量授权,

    status: 200(成功), return: 修改后的角色信息

    set_permission_to_role:
    角色--单个授权，一次只能授予角色一个permission，也可以取消一个permission status: 200(成功),

    return: 修改后的角色信息

    list:
    角色--获取列表 角色列表信息,

    status: 200(成功), return: 角色信息列表

    set_permission_to_role:
    给单个角色，单个授权，一次只能授予该角色一个permission，也可以取消一个permission

    status：200（成功）return：修改后的角色信息
    """
    queryset = RolesModel.objects.all()

    def get_serializer_class(self):
        if self.action == 'partial_update':
            return RolesPartialSerializer
        elif self.action == 'set_permission_to_role':
            return RoleSetPermissionSerializer
        else:
            return BaseRolesSerializer

    @action(methods=['post'], detail=False)
    def set_permission_to_role(self, request, *args, **kwargs):
        ser = RoleSetPermissionSerializer(data=request.data)
        if ser.is_valid():
            role = RolesModel.objects.get(id=ser.validated_data.get('role_id'))
            # 查询 当前的权限
            permission = PermissionsModel.objects.get(id=ser.validated_data.get('permission'))
            if ser.validated_data.get('is_create'):
                # 判断该权限所对应的父菜单权限是否被授权
                # 得到该权限对应的接口的父菜单
                parent_ids = MenuModel.objects.filter(id= permission.menu.id).values_list('parent',flat=True).all()
                if parent_ids:
                    parent_permission = PermissionsModel.objects.get(menu_id=parent_ids[0])
                    role.permissions.add(parent_permission)  # 把父菜单的权限也加上去
                role.permissions.add(permission)  # 把当前的权限授予当前角色
            else:  # 取消授权
                role.permissions.remove(permission)
            result_ser = BaseRolesSerializer(instance=role)
            return Response(data=result_ser.data)

    # 重写父类的删除函数，因为lrx角色不能删除
    def destroy(self, request, *args, **kwargs):
        if self.get_object().name == 'lrx':
            return Response(data={'detail': 'lrx角色不能删除'}, status=status.HTTP_400_BAD_REQUEST)
        return super().destroy(request, *args, **kwargs)

    del_ids = openapi.Schema(type=openapi.TYPE_OBJECT, required=['ids'], properties={
        'ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_INTEGER),
                              description='选择那些需要删除的id（主键）列表')
    })

    @swagger_auto_schema(method='delete', request_body=del_ids, operation_description='批量删除')
    @action(methods=['delete'], detail=False)
    def multiple_delete(self, request, *args, **kwargs):
        delete_ids = request.data.get('ids')
        try:
            admin = RolesModel.objects.get(name='lrx')
            if isinstance(delete_ids, list):
                if admin.id in delete_ids:
                    return Response(data={'detail': 'lrx角色不能删除'}, status=status.HTTP_400_BAD_REQUEST)
        except RolesModel.DoesNotExist as ex:
            pass
        return super().multiple_delete(request, *args, **kwargs)
